package com.eben.preferences;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import android.content.Context;
import android.content.SharedPreferences;

import com.eben.model.Highscore;
import com.eben.model.Score;

public class Preferences {
	private static String fileName = "highscore"; 
	private static String prefName = "HighScoreList";
	
	/**
	 * This method can save a highscore. It can be up to 10 highscores saved.
	 * It will check against earlier saved highscores and put this highscore in the correct place in the list,
	 * if the highscores is good enough to beat the other 10 scores. 
	 * 
	 * @param highscore
	 * @param context
	 */
	public static void setHighScore(Highscore highscore,Context context) {
		ArrayList<Highscore> arrayPrevHighscores = getHighscore(context); // get the list with previous saved highscore
		setLatestName(highscore.getName(), context);
		SharedPreferences settings = context.getSharedPreferences(fileName, 0); // Get preference and start editing it.
	    SharedPreferences.Editor editor = settings.edit();
	    
	    String save = ""; 
	    
		if(arrayPrevHighscores.isEmpty()){ //If we don't have any prev. saved highscores we just save the highscore
			save = highscore.toString();
		}else{							//else when there is earlier highscores we add the highscore to the arraylist and than sort it.
			arrayPrevHighscores.add(highscore); 
			sortHighscoreList(arrayPrevHighscores);
			if(arrayPrevHighscores.size() > 10){ // if there is more than 10 highscores in the list we will remove one
				arrayPrevHighscores.remove(10);	// we only add one highscore so we should not be able to get more than 11 Highscores in the list. and here we remove the lowest highscore
			}
			save = convertArrayToString(arrayPrevHighscores); 
		}
		
		editor.putString(prefName, save);  // change the highscore
	    editor.commit(); // save the highscores
	}
	
	/**
	 *  tell you if the score you have is a highscore compared to previus saved score
	 *    
	 * @param highscore
	 * @param context
	 * @return - a boolean telling you if your highscore "fit" on he list.
	 */
	public static Boolean isHighscore(Highscore highscore, Context context){
		ArrayList<Highscore> arrayPrevHighscores = getHighscore(context); // get the list with previous saved highscore
		
		if(arrayPrevHighscores.isEmpty()){ //If we don't have any prev. saved highscores, the score is a highscore
			return true;
		}else if(arrayPrevHighscores.size() < 10){ // if ther is less than 10 highscores, the score is higshcore
			return true;							
		}else{			//else when there is earlier highscores we add the highscore to the arraylist and than sort it.
			arrayPrevHighscores.add(highscore); 
			sortHighscoreList(arrayPrevHighscores);
			if(arrayPrevHighscores.get(10).equals(highscore)){ // if there is more than 10 highscores in the list we will remove one
				return false;
			}else{
				return true;
			}
		}
	}
	
	/**
	 * This method will return a ArrayList with highscores from earlier played games.
	 * if there is no highscores saved it will give an empty list.
	 * 
	 * @param context - the context assosiated with the saved scores (common: getHighscore(this))
	 * @return an ArrayList<Highscore> that contains all the highscores beginning with the "best"/"highest"
	 */
	public static ArrayList<Highscore> getHighscore(Context context) {
		SharedPreferences savedScores = context.getSharedPreferences(fileName, 0); 
    	String temp = savedScores.getString(prefName,"empty"); //get the score if there is no earlier score. give the String empty
    	ArrayList<Highscore> highscoreArray = convertStringToArray(temp);
    	sortHighscoreList(highscoreArray); // sort the array
    	return highscoreArray;
	}
	
	private static String convertArrayToString(ArrayList<Highscore> array){
		String temp = "";
		for(int i = 0; i < array.size(); i++){
			temp += array.get(i).toString() + ",";
		}
		if(temp.equals("")){
			temp = "empty";
		}
		return temp;
	}
	
	private static ArrayList<Highscore> convertStringToArray(String stringHighscore){
		ArrayList<Highscore> highscoreArrayList = new ArrayList<Highscore>();
		if(stringHighscore.equals("empty")){
			return highscoreArrayList;
		}
		String[] highscore = stringHighscore.split(",");
		for(int i = 0; i < highscore.length;i += 2){
			int scorePoint = Integer.parseInt(highscore[i+1]);
			highscoreArrayList.add(new Highscore(new Score(scorePoint), highscore[i]));
		}
		return highscoreArrayList;
	}
	
	/**
	 * Clean the highscoreList
	 */
	public static void cleanHighscores(Context context){
		SharedPreferences settings = context.getSharedPreferences(fileName, 0);
	    SharedPreferences.Editor editor = settings.edit();
	    editor.putString(prefName, null);
	    // Commit the edits!
	    editor.commit();
	}
	
	private static void setLatestName(String name, Context context){
		SharedPreferences settings = context.getSharedPreferences("LatestHighscoreName", 0); // Get preference and start editing it.
	    SharedPreferences.Editor editor = settings.edit();
		editor.putString("HighscoreName", name);
	    editor.commit();
		
	}
	/**
	 * Return the latest name that have been saved as a highscore
	 * 
	 * @param context
	 * @return a string with the name connected to the latest highscore 
	 */
	public static String getLatestName(Context context){
		SharedPreferences savedScores = context.getSharedPreferences("LatestHighscoreName", 0); 
    	String temp = savedScores.getString("HighscoreName","");
		return temp;
	}
	
	private static void sortHighscoreList(ArrayList<Highscore> arrayList){
		Collections.sort(arrayList, new Comparator<Highscore>() {
			/**
			 * This compares one highscore to another.
			 * equals give 0
			 * returns > 0 if the other highscore is greater than this
			 * returns < 0 if this highscore is greater than the other
			 * This comparison will give the highest highscore first in a list if you use Collection to sort it.
			 * 
			 * Note: this comparator imposes orderings that are inconsistent with ordinary compareTo."
			 */
			public int compare(Highscore object1, Highscore object2) {
				return object2.getScore().getScoreInt() - object1.getScore().getScoreInt();
			}
		});
	}
}
